package com.myway.service.order;

import com.myway.core.execption.IBEException;
import com.myway.core.spring.SpringBeanUtil;
import com.myway.dto.domain.OfficeInfo;
import com.myway.dto.domain.PassengerType;
import com.myway.dto.domain.TotalFlyPrice;
import com.myway.dto.ibe_param.TaxPrice;
import com.myway.dto.vo.FlyOrderVo;
import com.myway.dto.vo.FlyPassengeVo;
import com.myway.dto.vo.FlySegmentVo;
import com.myway.service.ibe.command.BaseIBECommand;
import com.myway.service.ibe.command.PNRCommand;
import com.myway.service.ibe.command.ReservePNRCommand;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by jid90 on 2018/9/10.
 */
@Slf4j
public class PNRManage {
    @Resource(name = "reservePNRCommand")
    private ReservePNRCommand reservePNRCommand;
    @Resource(name = "pnrCommand")
    private PNRCommand pnrCommand;

    private static final Logger log = Logger.getLogger(  PNRManage.class );
    private String airline;//airline....
    /**
     * @param airline
     */
    public PNRManage(String airline) {
        this.airline = airline;
    }
    private static Map<String,PNRManage> maps=new HashMap<String,PNRManage>();
    public static PNRManage getInstance(String airline){
        if(!maps.containsKey(airline)){
            PNRManage manage=new PNRManage(airline);
            maps.put(airline, manage);
        }
        return maps.get(airline);
    }
    /**
     * 此方法可以在web context中使用，MQ中请勿使用。
     * @return
     */
    public static PNRManage getDefaultInstance(){
        String airline= OfficeInfo.AIRLINE;
        return getInstance(airline);
    }
    /**
     * create pnr...
     * @param order dtoOrder....
     */
    public void creatPNR(FlyOrderVo order, TotalFlyPrice totalFlyPrice, List<TaxPrice> taxPrices){
        String contactNo = StringUtils.hasText(order.getContactMoble())?order.getContactMoble():order.getContactTel();
        //成人、儿童分别预定
        List<FlyPassengeVo> adultPassengers=new ArrayList<FlyPassengeVo>();
        List<FlyPassengeVo> childPassengers=new ArrayList<FlyPassengeVo>();
        List<FlyPassengeVo> infants=new ArrayList<FlyPassengeVo>();

        for(FlyPassengeVo pax:order.getPassenges()){
            if(pax.getPassageType().equals(PassengerType.ADULT) ){
                adultPassengers.add(pax);
                if(pax.getAccompanyingPassengerList()!=null&&pax.getAccompanyingPassengerList().size()>0){
                    for(FlyPassengeVo chd:pax.getAccompanyingPassengerList()){
                        if(chd.getPassageType().equals(PassengerType.CHILD)){
                            chd.setAccompaniedByPassenger(pax);
                            childPassengers.add(chd);
                        }
                    }
                }
            }
            else if(pax.getPassageType().equals(PassengerType.CHILD)){
                childPassengers.add(pax);
            }else if(pax.getPassageType().equals(PassengerType.INFANT)){
                infants.add(pax);
            }else{
                log.debug("No handle this condition....");
            }
        }
        //DTO对象中婴儿、儿童自动关联成人
        List<FlyPassengeVo> new_adultPassengers=new ArrayList<FlyPassengeVo>();
        new_adultPassengers=adultPassengers;
//        audltPassengerHelper(new_adultPassengers, childPassengers, infants);
        order.setPassenges(new_adultPassengers);//成人带婴儿

        String adultPnr="";
        if(!new_adultPassengers.isEmpty()){
            adultPnr=creatPNR(order.getSegments(), new_adultPassengers,totalFlyPrice,taxPrices, contactNo,order);
        }
        //儿童列表必须在成人生成完后，加入旅客列表，否则影响成人列表结构
        order.getPassenges().addAll(childPassengers);//儿童
        if(!childPassengers.isEmpty()){
            try {
                creatPNR(order.getSegments(), childPassengers,totalFlyPrice,taxPrices, contactNo,order);
            } catch (Exception e) {
                // reserver child Pnr error...
                log.error(e.getMessage(),e);
                //已预订成人编码

                if (StringUtils.hasText(adultPnr)) {
                    // cancel adult pnr
					/*PnrManage pnrMgr = new PnrManage();
					configIBEClient(pnrMgr, order.getAirlineCode());
					log.debug("try to delete pnr:"+adultPnr);
					try {
						pnrMgr.deletePnr(adultPnr);
					} catch (Exception e1) {
						log.error("cancel pnr error ,pnr no:"+adultPnr);
					}*/
//                    cancelPnr4OrderCreatError(adultPnr, order);
                    pnrCommand = (PNRCommand) SpringBeanUtil.lookup("pnrCommand");
                    pnrCommand.cancelPnr(adultPnr);
                }
                throw new IBEException(e);
            }
        }
    }

    /**
     * @名称：creatPNR
     * @描述：创建PNR
     * @param segmentList
     * @param passengerList
     * @param contactNo
     * @param order
     * @return
     */
    public String creatPNR(List<FlySegmentVo> segmentList, List<FlyPassengeVo> passengerList,TotalFlyPrice totalFlyPrice, List<TaxPrice> taxPrices,
                           String contactNo, FlyOrderVo order) {
        Map<String,Object> parms=new HashMap<String,Object>();
        parms.put("segments", segmentList);
        parms.put("passenges", passengerList);
        parms.put("contactNo", contactNo);
        parms.put("totalFlyPrice",totalFlyPrice);
        parms.put("taxPrices",taxPrices);
        parms.put("order", order);
       /* System.out.println("=======@@@=====》》》 生成pnr parms参数是="+parms.toString());*/
        reservePNRCommand = (ReservePNRCommand) SpringBeanUtil.lookup("reservePNRCommand");
        reservePNRCommand.execute(parms);
        return (String)parms.get("PNRNo");
    }

    /**
     * @名称：audltPassengerHelper
     * @描述：匹配成人携带儿童、婴儿
     * 每个成人带两个儿童（含婴儿），每个成人只能带一个婴儿
     * @param adultPassengers
     * @param childPassengers
     * @param infants
     */
    public static void audltPassengerHelper(List<FlyPassengeVo> adultPassengers,List<FlyPassengeVo> childPassengers,List<FlyPassengeVo> infants){
        if(CollectionUtils.isNotEmpty(infants)&&CollectionUtils.isNotEmpty(adultPassengers)){//成人携带婴儿
            if(infants.size()<=adultPassengers.size()){
                for(FlyPassengeVo inf:infants){
                    for(FlyPassengeVo adultpax:adultPassengers){
                        if(adultpax.getAccompanyingPassengerList()==null||adultpax.getAccompanyingPassengerList().size()==0){
                            List<FlyPassengeVo> infantList=new ArrayList<FlyPassengeVo>();
                            infantList.add(inf);
                            adultpax.setAccompanyingPassengerList(infantList);
                            inf.setAccompaniedByPassenger(adultpax);
                            break;
                        }else if(adultpax.getAccompanyingPassengerList().size()==1&&adultpax.getAccompanyingPassengerList().get(0).getPassageType().equals(PassengerType.CHILD)){
                            //携带过儿童的成人
                            adultpax.getAccompanyingPassengerList().add(inf);
                            inf.setAccompaniedByPassenger(adultpax);
                            break;
                        }
                    }
                    //没有被携带的婴儿
                }
            }else{
                //FIXME 如果婴儿超出携带上限，按儿童购票
            }
        }
        if(CollectionUtils.isNotEmpty(childPassengers)&&CollectionUtils.isNotEmpty(adultPassengers)){
            for(FlyPassengeVo ch:childPassengers){
                for(FlyPassengeVo audlt:adultPassengers){
                    if(audlt.getAccompanyingPassengerList()==null)audlt.setAccompanyingPassengerList(new ArrayList<FlyPassengeVo>());
                    if(audlt.getAccompanyingPassengerList().size()<2){
                        audlt.getAccompanyingPassengerList().add(ch);
                        ch.setAccompaniedByPassenger(audlt);
                        break;
                    }
                }
                //FIXME 如果没有携带人，异常
            }
        }
    }
}
